package monfox.stack.iec61850.mms.client.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;

import monfox.log.Logger;
import monfox.stack.iec61850.api.ModelCommunicationException;
import monfox.stack.iec61850.api.ModelServiceException;
import monfox.stack.iec61850.api.ModelTimeoutException;
import monfox.stack.iec61850.api.ModelValueException;
import monfox.stack.osi.api.CommunicationsException;
import monfox.stack.osi.api.TimeoutException;
import monfox.stack.osi.api.ValueException;
import monfox.stack.osi.mms.MMS_GetNameList_PendingRequest;
import monfox.stack.osi.mms.MMS_GetNameList_Req;
import monfox.stack.osi.mms.MMS_GetNameList_Rsp;
import monfox.stack.osi.mms.MMS_GetNamedVariableListAttributes_PendingRequest;
import monfox.stack.osi.mms.MMS_GetNamedVariableListAttributes_Req;
import monfox.stack.osi.mms.MMS_GetNamedVariableListAttributes_Rsp;
import monfox.stack.osi.mms.ObjectClass;
import monfox.stack.osi.mms.ObjectName;
import monfox.stack.osi.mms.ObjectScope;
import monfox.stack.osi.mms.Variable;

public class ACSI_GetDirectory extends ACSI_Service {
    private ACSI.DirectoryType a = null;
    private boolean b = false;
    private String c = null;
    private String d = null;
    private Listener e = null;
    private String f = "########";
    private ObjectName g;
    private MMS_GetNameList_PendingRequest h = null;
    private MMS_GetNamedVariableListAttributes_PendingRequest i = null;
    private static Logger j = Logger.getInstance("DOSI", "IEC61850-SERVICES", "ACSI_GetDirectory");

    public ACSI_GetDirectory(MmsIEC61850Client paramMmsIEC61850Client, ACSI.DirectoryType paramDirectoryType)
            throws ModelServiceException {
        this(paramMmsIEC61850Client, paramDirectoryType, null);
    }

    public ACSI_GetDirectory(MmsIEC61850Client paramMmsIEC61850Client, ACSI.DirectoryType paramDirectoryType,
                             String paramString) throws ModelServiceException {
        super(paramMmsIEC61850Client, "GetDirectory");

        paramString = getClient().convert2mms(paramString);

        if ((paramDirectoryType != ACSI.DeviceList) && (paramString == null)
                && (paramMmsIEC61850Client.getDefaultLDeviceName() == null)) {
            throw new ModelServiceException("expected device name for directory type '" + paramDirectoryType + "'");
        }

        if (paramDirectoryType == ACSI.DataSetMemberList) {
            if (paramString == null) {
                throw new ModelServiceException("expected DataSet object name name (<Device>/<DSName>)");
            }

            this.g = a(paramString);

            this.c = this.g.getDomainID();
            this.d = this.g.getItemID();
        } else if (paramDirectoryType == ACSI.LogList) {
            if (paramString == null) {
                throw new ModelServiceException("expected DataSet object name name (<Device>/<LN>)");
            }

            this.g = a(paramString);

            this.c = this.g.getDomainID();
            this.d = this.g.getItemID();
        } else {
            this.c = paramString;

            if (this.c == null) {
                this.c = paramMmsIEC61850Client.getDefaultLDeviceName();
            }
        }

        this.a = paramDirectoryType;
    }

    public String getLDeviceName() {
        return this.c;
    }

    public String getElementName() {
        return this.d;
    }

    public ACSI.DirectoryType getDirectoryType() {
        return this.a;
    }

    public void isMoreFollowsValid(boolean paramBoolean) {
        this.b = paramBoolean;
    }

    public boolean isMoreFollowsValid() {
        return this.b;
    }

    public Result getResult() throws ModelServiceException, ModelCommunicationException, ModelValueException {
        return (Result) d();
    }

    final void a() throws ModelCommunicationException, ModelValueException {
        ACSI_GetDirectory localACSI_GetDirectory;
        if (this.a == ACSI.DataSetMemberList) {
            localACSI_GetDirectory = this;
            try {
                MMS_GetNamedVariableListAttributes_Req localMMS_GetNamedVariableListAttributes_Req;
                if (localACSI_GetDirectory.g != null)
                    localMMS_GetNamedVariableListAttributes_Req = new MMS_GetNamedVariableListAttributes_Req(
                            localACSI_GetDirectory.g);
                else
                    localMMS_GetNamedVariableListAttributes_Req = new MMS_GetNamedVariableListAttributes_Req(
                            ObjectName.Domain(localACSI_GetDirectory.c, localACSI_GetDirectory.d));
                localACSI_GetDirectory.i = localACSI_GetDirectory.getValidMMS().send(
                        localMMS_GetNamedVariableListAttributes_Req, localACSI_GetDirectory.getTimeoutMillis());
            } catch (CommunicationsException localCommunicationsException2) {
                throw new ModelCommunicationException("communications error on send", localCommunicationsException2);
            } catch (ValueException localValueException2) {
                throw new ModelValueException("value exception error on send", localValueException2);
            }
        } else {
            localACSI_GetDirectory = this;
            Object localObject = ObjectClass.domain;
            ObjectScope localObjectScope = ObjectScope.vmdSpecific;
            switch (localACSI_GetDirectory.a.intValue()) {
                case 0:
                    localObject = ObjectClass.domain;
                    localObjectScope = ObjectScope.vmdSpecific;
                    break;
                case 2:
                    localObject = ObjectClass.journal;
                    break;
                case 1:
                    localObject = ObjectClass.namedVariable;
                    localObjectScope = ObjectScope.domainSpecific(this.c);
                    break;
                case 3:
                    localObject = ObjectClass.namedVariableList;
                    if ((localACSI_GetDirectory.c == null) || (localACSI_GetDirectory.c.length() == 0)
                            || (localACSI_GetDirectory.c.equals("/")))
                        localObjectScope = ObjectScope.vmdSpecific;
                    else if (localACSI_GetDirectory.c.equals("@"))
                        localObjectScope = ObjectScope.aaSpecific;
                    else
                        localObjectScope = ObjectScope.domainSpecific(localACSI_GetDirectory.c);
            }
            localObject = new MMS_GetNameList_Req((ObjectClass) localObject, localObjectScope);
            try {
                localACSI_GetDirectory.h = localACSI_GetDirectory.getValidMMS().send((MMS_GetNameList_Req) localObject,
                        localACSI_GetDirectory.getTimeoutMillis());
                return;
            } catch (CommunicationsException localCommunicationsException1) {
                throw new ModelCommunicationException("communications error on send", localCommunicationsException1);
            } catch (ValueException localValueException1) {
                throw new ModelValueException("value exception error on send", localValueException1);
            }

        }
    }

    final synchronized void b() throws ModelCommunicationException, ModelValueException, ModelTimeoutException {
        if (this.a == ACSI.DataSetMemberList) {
            f();
            return;
        }

        g();
    }

    private synchronized void f() throws ModelCommunicationException, ModelValueException, ModelTimeoutException {
        if (this.i == null) {
            return;
        }

        Vector localVector = new Vector();
        try {
            MMS_GetNamedVariableListAttributes_Rsp rsp = this.i.rsp();
            ListIterator iter = rsp.getVariableList().listIterator();

            while ((iter).hasNext()) {
                ObjectName localObjectName;
                Variable var = (Variable) iter.next();
                if (var.getName() != null) {
                    localVector.add(var.getName().getDomainID() + "/"
                            + getClient().convert2model(var.getName().getItemID()));
                } else {
                    j.error("invalid Variable format for GetDataSetDirectory (expected 'name'): " + var);
                }
            }

            Object localObject2 = new Result(localVector);
            a((ACSI_Service.Result) localObject2);

            return;
        } catch (TimeoutException localTimeoutException) {
            throw new ModelTimeoutException("timeout", localTimeoutException);
        }
    }

    private synchronized void g() throws ModelCommunicationException, ModelValueException, ModelTimeoutException {
        if (this.h == null) {
            return;
        }

        List<String> localVector = new ArrayList<String>();

        String after = null;
        while (this.h != null) {
            MMS_GetNameList_Rsp localMMS_GetNameList_Rsp;
            try {
                localMMS_GetNameList_Rsp = this.h.rsp();
            } catch (TimeoutException localTimeoutException) {
                throw new ModelTimeoutException("timeout", localTimeoutException);
            }

            if (localMMS_GetNameList_Rsp.isError()) {
                // localObject = new
                // ModelServiceException("error in getting directory ("
                // + localTimeoutException.getServiceError() + ")");

                // j.comms("service error", (Throwable) localObject);
                // a(b((ModelServiceException) localObject));
                // return;
                break;
            }
            if (localMMS_GetNameList_Rsp.isReject()) {
                // localObject = new
                // ModelServiceException("error in getting directory ("
                // + ((MMS_GetNameList_Rsp) localObject).getReject() + ")");
                //
                // j.comms("rejected", (Throwable) localObject);
                // a(b((ModelServiceException) localObject));
                // return;
                break;
            }

            if (localMMS_GetNameList_Rsp.getIdentifiers().size() > 0) {
                if (localVector.contains(getClient().convert2model(
                        (String) localMMS_GetNameList_Rsp.getIdentifiers().get(0))))
                    break;
                for (Object iter : localMMS_GetNameList_Rsp.getIdentifiers()) {
                    String str = (String) iter;

                    localVector.add(getClient().convert2model(str));
                }
                int size = localMMS_GetNameList_Rsp.getIdentifiers().size();
                after = (String) localMMS_GetNameList_Rsp.getIdentifiers().get(size - 1);
            } else {
                break;
            }
            if (this.h.getRequest().getObjectClass() != ObjectClass.namedVariable) {
                break;
            }

            MMS_GetNameList_Req req = new MMS_GetNameList_Req(ObjectClass.namedVariable,
                    ObjectScope.domainSpecific(this.c));// this.h.newContinuationRequest(isMoreFollowsValid());
            // if (req == null) {
            // break;
            // }
            req.setContinueAfter(after);

            // localVector.contains(this.f);
            try {
                this.h = getClient().getValidMMS().send(req, getTimeoutMillis());
            } catch (CommunicationsException localCommunicationsException) {
                throw new ModelCommunicationException("communications error on send", localCommunicationsException);
            } catch (ValueException localValueException) {
                throw new ModelValueException("value exception error on send", localValueException);
            }
        }
        if ((this.a == ACSI.DeviceList) && (localVector.size() > 0) && (getClient().getDefaultLDeviceName() == null)) {
            getClient().setDefaultLDeviceName((String) localVector.get(0));
        }

        Object localObject = new Result(localVector);
        a((ACSI_Service.Result) localObject);
    }

    private Result b(ModelServiceException paramModelServiceException) {
        return new Result(paramModelServiceException);
    }

    final void c() {
        if (this.e == null)
            return;
        try {
            this.e.handleResult(this);

            return;
        } catch (Exception localException) {
            j.error("exception in listener invocation", localException);
        }
    }

    public void setListener(Listener paramListener) {
        this.e = paramListener;
    }

    public Listener getListener() {
        return this.e;
    }

    public ACSI_GetDirectory send() throws ModelServiceException, ModelCommunicationException, ModelValueException {
        return (ACSI_GetDirectory) e();
    }

    public class Result extends ACSI_Service.Result {
        private List<String> a = null;

        Result(ModelServiceException arg2) {
            super(arg2);
        }

        Result(List<String> list) {
            super();
            Object localObject;
            this.a = list;
        }

        public List<String> getNameList() {
            return this.a;
        }

        public String toString() {
            StringBuffer localStringBuffer = new StringBuffer();
            toString(localStringBuffer);
            return localStringBuffer.toString();
        }

        public void toString(StringBuffer paramStringBuffer) {
            paramStringBuffer.append("\n--[ GetDirectory.Result ]---------------------------");
            paramStringBuffer.append("\n");
            if (this.a != null) {
                paramStringBuffer.append("\n   logicalNodeList: ");
                paramStringBuffer.append("\n");
                ListIterator localListIterator = this.a.listIterator();
                while (localListIterator.hasNext()) {
                    String str = (String) localListIterator.next();
                    paramStringBuffer.append("\n      ").append(str);
                }
            }

            if (getException() != null) {
                paramStringBuffer.append("\n   exception:");
                paramStringBuffer.append("\n");
                paramStringBuffer.append(getException().getMessage());
            }

            paramStringBuffer.append("\n");
            paramStringBuffer.append("\n--[ GetDirectory.Result ]---------------------------");
        }
    }

    public static abstract interface Listener {
        public abstract void handleResult(ACSI_GetDirectory paramACSI_GetDirectory);
    }

    @Override
    monfox.stack.iec61850.mms.client.impl.ACSI_Service.Result a(ModelServiceException paramModelServiceException) {
        // TODO Auto-generated method stub
        return null;
    }
}